﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.OleDb;
using System.Windows;
using System.Net;
using System.Runtime.InteropServices;

namespace AutoMeasureV2._1
{

    public class fileHandle
    {

        #region 声明读写INI文件的API函数

        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section,
            string key, string val, string filePath);//写入INI函数 

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section,
            string key, string defVal, StringBuilder retVal, int size, string filePath);//读取INI函数

        /// <summary>
        /// ini文件读取
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public string IniReadValue(string section, string key, string filePath)
        {
            StringBuilder temp = new StringBuilder(255);
            int i = GetPrivateProfileString(section, key, "", temp, 255, filePath);
            return temp.ToString();
        }

        #endregion

        public Dictionary<int, Band> _band = new Dictionary<int, Band>();
        public List<Source> source = new List<Source>();
        public Dictionary<int, string> tableName = new Dictionary<int, string>();
        private Dictionary<string, List<TableMessage>> _tableMessage = new Dictionary<string, List<TableMessage>>();
        public Dictionary<string, List<TableMessage>> TableMessage
        {
            get { return _tableMessage; }
            set { _tableMessage = value; }
        }

        /// <summary>
        /// 将excel表格数据导入内存
        /// </summary>
        /// <param name="strFilenName">excel文件地址</param>
        public void ExceltoDataTable(string strFileName)
        {
            string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strFileName + ";Extended Properties='Excel 8.0;HDR=No;IMEX=1;'";
            OleDbConnection conn = new OleDbConnection(strConn);
            conn.Open();
            DataTable dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" });
            tableName.Clear();
            TableMessage.Clear();

            for (int k = 0; k < dtSheetName.Rows.Count; k++)
            {
                tableName.Add(k, dtSheetName.Rows[k]["TABLE_NAME"].ToString());
            }

            foreach (var item in tableName)
            {
                List<TableMessage> _tableInfo = new List<TableMessage>();
                string strExcel = "select*from[" + item.Value + "]";

                OleDbDataAdapter myCommand = null;
                DataTable dt = new DataTable();
                myCommand = new OleDbDataAdapter(strExcel, strConn);
                myCommand.Fill(dt);

                int row = dt.Rows.Count;       //行总数
                int col = dt.Columns.Count;    //列总数
                int timeCount=0;
                for (int k = 0; k < row; k++)
                {
                    if (dt.Rows[k][1].ToString() !=string .Empty  )
                        timeCount++;
                    else
                        break;
                }

                for (int i = 1; i < col - 1; i++)
                {
                    TableMessage _tabMes = new TableMessage();
                    string tName = dt.Rows[0][i].ToString().ToUpper().Trim();
                    _tabMes.tableColumn = tName;

                    for (int j = 1; j < timeCount; j++)
                    {
                        string tValue = dt.Rows[j][i].ToString().ToUpper().Trim();

                        _tabMes.tableRow.Add(tValue);
                    }
                    _tableInfo.Add(_tabMes);
                }
                TableMessage.Add(item.Value, _tableInfo);
            }
        }

        /// <summary>
        /// 编写试验文件资源信息部分
        /// </summary>
        /// <param name="xmlPath">试验文件地址</param>
        public void xmlInfo(string setName)
        {
            ReadBinding();
            source.Clear();
            foreach (var item in _band)
            {
                Source _source = new Source();
                _source.UseName = item.Value.MesName;     //资源名称
                _source.UseID = item.Value.MesID;         //资源编号
                _source.ObjID = item.Value.ObjID;         //对象名称
                _source.ObjAddress = Convert.ToString(item.Value.ObjIP);         //对象地址
                _source.ObjPort = Convert.ToString(item.Value.ObjPort);          //对象端口
                _source.ObjDigType = Convert.ToString(item.Value.ObjDigit);      //数据类型
                _source.ObjSign = item.Value.ObjSign;     //识别码
                source.Add(_source);

                foreach (var items in TableMessage)
                {
                    if (items.Key == setName)
                    {
                        int count = items.Value.Count;

                        for (int i = 0; i < count; i++)
                        {
                            if (item.Value.MesName == items.Value[i].tableColumn)
                            {
                                switch (Convert.ToString(item.Value.ObjDigit))
                                {
                                    case "0":
                                        _source.Steps = writeAnalog(items.Value[i].tableRow, items.Value[0].tableRow);
                                        break;
                                    case "1":
                                        _source.Steps = writeDigit(items.Value[i].tableRow, items.Value[0].tableRow);
                                        break;
                                    case "2":
                                        _source.Steps = writeSwitch(items.Value[i].tableRow, items.Value[0].tableRow);
                                        break;
                                    default:
                                        break;
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }

        #region  数字量模拟量开关量写入XML函数
        /// <summary>
        /// 模拟量xml写入公式
        /// </summary>
        /// <param name="mesList">指令集</param>
        /// <param name="timeList">时间集</param>
        /// <returns>工步集</returns>
        private List<Step> writeAnalog(List<string> mesList, List<string> timeList)
        {
            List<Step> nstep = new List<Step>();
            Dictionary<int, string> AnalogData = new Dictionary<int, string>();
            AnalogData = zhengze.handleMessage(mesList, timeList);

            if (AnalogData.Count % 2 == 0)
            {
                List<int> newTimeList = new List<int>();
                List<string> newMesList = new List<string>();
                foreach (var item in AnalogData)
                {
                    newTimeList.Add(item.Key);
                    newMesList.Add(item.Value);
                }

                for (int k = 0; k < newTimeList.Count / 2; k++)
                {

                    string stepMes = newMesList[2 * k];
                    string stepMes2 = newMesList[2 * k + 1];
                    if (stepMes == stepMes2)
                    {
                        Step nnstep = new Step();
                        nnstep.StepNum = k + 1;
                        nnstep.TargetValue = double.Parse(stepMes);
                        nnstep.OrderTime = Convert.ToDouble(newTimeList[2 * k]);
                        nnstep.ChangeTime = Convert.ToDouble(newTimeList[2 * k + 1] - newTimeList[2 * k]);
                        nstep.Add(nnstep);
                    }
                    else
                    {
                        MessageBox.Show("模拟量格式错误");
                        break;
                    }

                }
            }
            else
                MessageBox.Show("模拟量格式错误");
            return nstep;
        }

        /// <summary>
        /// 数字量xml写入公式
        /// </summary>
        /// <param name="mesList">指令集</param>
        /// <param name="timeList">时间集</param>
        /// <returns>工步集</returns>
        private List<Step> writeDigit(List<string> mesList, List<string> timeList)
        {
            List<Step> nstep = new List<Step>();

            Dictionary<int, string> AnalogData = new Dictionary<int, string>();
            AnalogData = zhengze.handleMessage(mesList, timeList);
            List<int> newTimeList = new List<int>();
            List<string> newMesList = new List<string>();

            foreach (var item in AnalogData)
            {
                newTimeList.Add(item.Key);
                newMesList.Add(item.Value);
            }
            int digitCount = AnalogData.Count;
            for (int k = 0; k < digitCount; k++)
            {
                Step nnstep = new Step();
                nnstep.StepNum = k + 1;
                nnstep.TargetValue = double.Parse(newMesList[k]);
                nnstep.OrderTime = Convert.ToDouble(newTimeList[k]);
                nnstep.ChangeTime = 0;
                nstep.Add(nnstep);
            }
            return nstep;
        }

        /// <summary>
        /// 开关量xml写入公式
        /// </summary>
        /// <param name="mesList">指令集</param>
        /// <param name="timeList">时间集</param>
        /// <returns>工步集</returns>
        private List<Step> writeSwitch(List<string> mesList, List<string> timeList)
        {
            List<Step> nstep = new List<Step>();

            Dictionary<int, string> AnalogData = new Dictionary<int, string>();
            AnalogData = zhengze.handleMessage(mesList, timeList);
            List<int> newTimeList = new List<int>();
            List<string> newMesList = new List<string>();
            foreach (var item in AnalogData)
            {
                newTimeList.Add(item.Key);
                newMesList.Add(item.Value);
            }

            int switchCount = AnalogData.Count;
            for (int k = 0; k < switchCount; k++)
            {
                Step nnstep = new Step();
                nnstep.StepNum = k;
                nnstep.TargetValue = double.Parse(newMesList[k]);
                nnstep.OrderTime = Convert.ToDouble(newTimeList[k]);
                nnstep.ChangeTime = 0;
                nstep.Add(nnstep);
            }

            return nstep;
        }

        #endregion

        /// <summary>
        /// 读取资源绑定信息
        /// </summary>
        void ReadBinding()
        {
            try
            {
                string BandFile = AppDomain.CurrentDomain.BaseDirectory + @"配置文件\Band.ini";
                string Num = IniReadValue("Info", "Num", BandFile);
                int num = Convert.ToInt16(Num);
                _band.Clear();
                for (int i = 0; i < num; i++)
                {
                    Band _bandSins = new Band();
                    string section = "BAND" + Convert.ToString(i);

                    string messageName = IniReadValue(section, "MessageName", BandFile);
                    string messageID = IniReadValue(section, "MessageID", BandFile);
                    string objName = IniReadValue(section, "ObjName", BandFile);
                    IPAddress objIP = IPAddress.Parse(IniReadValue(section, "ObjIP", BandFile));
                    double objPort = double.Parse(IniReadValue(section, "ObjPort", BandFile));
                    string objSign = IniReadValue(section, "ObjSign", BandFile);
                    string objID = IniReadValue(section, "ObjID", BandFile);
                    double objOrder = double.Parse(IniReadValue(section, "ObjOrder", BandFile));
                    double objRespond = double.Parse(IniReadValue(section, "ObjRespond", BandFile));
                    double objDigit = double.Parse(IniReadValue(section, "ObjDigit", BandFile));

                    _bandSins.MesName = messageName;
                    _bandSins.MesID = messageID;
                    _bandSins.ObjID = objID;
                    _bandSins.ObjIP = objIP;
                    _bandSins.ObjPort = objPort;
                    _bandSins.ObjOrder = objOrder;
                    _bandSins.ObjRespond = objRespond;
                    _bandSins.ObjDigit = objDigit;
                    _bandSins.ObjSign = objSign;
                    _band.Add(i, _bandSins);
                }
            }
            catch
            {
                MessageBox.Show("绑定信息错误，请检查");
            }
        }
    }

    public class TableMessage
    {
        public string tableColumn { get; set; }                  //表头
        private List<string> _tableRow = new List<string>();
        public List<string> tableRow
        {
            get { return _tableRow; }
            set { _tableRow = value; }
        }
    }

    /// <summary>
    /// 资源信息序列
    /// </summary>
    public class Source
    {
        public string UseName { get; set; }               //资源名称
        public string UseID { get; set; }                 //资源编号
        public string ObjID { get; set; }               //对象名称
        public string ObjAddress { get; set; }            //对象地址
        public string ObjPort { get; set; }                  //对象端口
        public string ObjDigType { get; set; }               //数据类型
        public string ObjSign { get; set; }                 //识别码
        public int StepCount { get { return _steps.Count; } } //工步数量

        private List<Step> _steps = new List<Step>();     //工步对象
        public List<Step> Steps
        {
            get { return _steps; }
            set { _steps = value; }
        }
    }

    /// <summary>
    /// 工步信息序列
    /// </summary>
    public class Step
    {
        public Source Source { get; set; }               //工步资源信息
        public int StepNum { get; set; }                 //序号
        public double OrderTime { get; set; }            //指令时间
        public double TargetValue { get; set; }          //指令结果
        public double ChangeTime { get; set; }           //动作时间
    }
}
